from docx import Document
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.dml.color import RGBColor
import re
import os
import requests
import json
import time
from pathlib import Path

class DocxToPptConverter:
    def __init__(self, api_key=None):
        self.doc_content = []
        self.images_folder = "media"
        self.api_key = api_key
        self.use_api = False
        
        # 检查API密钥有效性
        if api_key:
            self.use_api = self._validate_api_key(api_key)
    
    def _validate_api_key(self, api_key):
        """验证API密钥格式"""
        if not api_key or api_key.strip() == "":
            print("❌ API密钥为空")
            return False
        elif "your_deepseek_api_key_here" in api_key:
            print("❌ 请替换默认的API密钥占位符")
            return False
        elif len(api_key) < 20:
            print("❌ API密钥格式可能不正确")
            return False
        else:
            print(f"✓ API密钥格式验证通过")
            return True
    
    def call_deepseek_api(self, prompt, content, max_retries=3):
        """调用DeepSeek API进行内容提炼"""
        if not self.use_api:
            return None
            
        url = "https://api.deepseek.com/chat/completions"
        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {self.api_key}"
        }
        
        full_prompt = f"{prompt}\n\n原文内容：\n{content[:3000]}"
        
        data = {
            "model": "deepseek-chat",
            "messages": [
                {
                    "role": "user",
                    "content": full_prompt
                }
            ],
            "temperature": 0.3,
            "max_tokens": 2000
        }
        
        print(f"🔄 调用DeepSeek API中...")
        
        for attempt in range(max_retries):
            try:
                response = requests.post(url, headers=headers, json=data, timeout=60)
                
                if response.status_code == 200:
                    result = response.json()
                    content = result['choices'][0]['message']['content']
                    print("✓ API调用成功")
                    return content
                elif response.status_code == 401:
                    print("❌ API密钥无效或已过期")
                    return None
                elif response.status_code == 429:
                    print("⚠ API调用频率限制，等待后重试...")
                    time.sleep(5)
                else:
                    print(f"❌ API调用失败，状态码: {response.status_code}")
                    if attempt < max_retries - 1:
                        time.sleep(3)
            except Exception as e:
                print(f"❌ API调用异常: {str(e)}")
                if attempt < max_retries - 1:
                    time.sleep(3)
        
        return None

    def summarize_section(self, section_title, content):
        """对章节内容进行总结提炼"""
        if not self.use_api or not content:
            return self._extract_key_points(content, 6)
        
        prompt = f"""请将以下技术文档内容提炼成3-6个核心要点，用于PPT展示。要求：
1. 每个要点简洁明了，不超过30字
2. 使用技术术语但要易于理解
3. 突出重点概念和关键信息
4. 避免细节描述，保持宏观视角
5. 用中文回答，使用项目符号格式

章节标题：{section_title}"""
        
        full_content = "\n".join(content[:10])
        summary = self.call_deepseek_api(prompt, full_content)
        
        if summary:
            points = self._parse_api_response(summary)
            if points:
                print(f"✓ 已AI提炼章节: {section_title}")
                return points
        
        return self._extract_key_points(content, 6)
    
    def summarize_chapter(self, chapter_title, sections):
        """对整章内容进行概述"""
        if not self.use_api:
            return "本章主要介绍相关概念和技术原理。"
        
        section_titles = [f"{s['number']} {s['title']}" for s in sections]
        sections_text = "、".join(section_titles[:5])
        
        prompt = f"""请为以下技术章节撰写一段简洁的概述，用于PPT章节标题页。要求：
1. 长度在50-100字之间
2. 概括本章的核心内容和学习重点
3. 语言精炼专业
4. 用中文回答

章节标题：{chapter_title}
包含小节：{sections_text}"""
        
        overview = self.call_deepseek_api(prompt, "")
        return overview if overview else "本章系统介绍相关理论知识和实践应用。"
    
    def create_executive_summary(self, structure):
        """生成执行摘要"""
        if not self.use_api:
            return self._create_basic_summary(structure)
        
        chapters_desc = []
        for chapter in structure['chapters']:
            sections = [f"{s['number']} {s['title']}" for s in chapter['sections']]
            chapters_desc.append(f"{chapter['title']}（包含：{'、'.join(sections[:3])}等）")
        
        doc_structure = "\n".join(chapters_desc)
        
        prompt = f"""请为以下技术文档生成一个执行摘要，用于PPT的总结页。要求：
1. 提炼文档的5-8个核心要点
2. 每个要点用•开头，简洁有力
3. 突出技术重点和关键概念
4. 体现文档的价值和实用性
5. 用中文回答

文档结构：
{doc_structure}"""
        
        summary = self.call_deepseek_api(prompt, "")
        if summary:
            points = self._parse_api_response(summary)
            if points:
                print("✓ AI生成执行摘要完成")
                return points
        
        return self._create_basic_summary(structure)
    
    def _parse_api_response(self, text):
        """解析API返回的文本，提取要点"""
        points = []
        lines = text.split('\n')
        
        for line in lines:
            line = line.strip()
            if re.match(r'^[•·\-*\d\.、]', line):
                clean_line = re.sub(r'^[•·\-*\d\.、\s]+', '', line)
                if clean_line and len(clean_line) > 5 and len(clean_line) < 100:
                    points.append(clean_line)
            elif len(line) > 10 and len(line) < 80 and not line.startswith('#'):
                points.append(line)
        
        return points if points else None
    
    def _create_basic_summary(self, structure):
        """创建基础总结（API不可用时使用）"""
        points = []
        for chapter in structure['chapters']:
            points.append(f"• {chapter['title']}的核心概念")
            for section in chapter['sections'][:2]:
                points.append(f"• {section['title']}的关键要点")
        return points[:8]

    def read_docx(self, docx_path):
        """读取Word文档并提取内容和结构"""
        try:
            if not os.path.exists(docx_path):
                print(f"错误: 文件 '{docx_path}' 不存在!")
                return False
                
            if not docx_path.lower().endswith('.docx'):
                print(f"错误: 文件 '{docx_path}' 不是有效的Word文档(.docx)!")
                return False
            
            doc = Document(docx_path)
            self.doc_content = []
            
            for paragraph in doc.paragraphs:
                text = paragraph.text.strip()
                if not text:
                    continue
                    
                if paragraph.style.name.startswith('Heading'):
                    level = int(paragraph.style.name.split()[-1]) if paragraph.style.name.split()[-1].isdigit() else 1
                    self.doc_content.append({
                        'type': 'heading',
                        'level': level,
                        'text': text,
                        'style': paragraph.style.name
                    })
                else:
                    self.doc_content.append({
                        'type': 'paragraph',
                        'text': text,
                        'style': paragraph.style.name
                    })
            
            print(f"成功读取文档，共提取 {len(self.doc_content)} 个段落")
            return True
            
        except Exception as e:
            print(f"读取Word文档时出错: {str(e)}")
            return False
    
    def analyze_content_structure(self):
        """分析文档结构，识别章节和内容"""
        structure = {
            'title': '',
            'chapters': [],
            'sections': [],
            'key_points': []
        }
        
        current_chapter = None
        current_section = None
        
        for item in self.doc_content:
            if item['type'] == 'heading':
                text = item['text']
                
                # 识别章节标题
                chapter_match = re.search(r'第[零一二三四五六七八九十\d]+章\s*(.+)', text)
                if chapter_match:
                    current_chapter = {
                        'title': chapter_match.group(1).strip(),
                        'sections': []
                    }
                    structure['chapters'].append(current_chapter)
                    current_section = None
                    continue
                
                # 识别小节标题
                section_match = re.search(r'(\d+\.\d+)\s*(.+)', text)
                if section_match and current_chapter:
                    current_section = {
                        'number': section_match.group(1),
                        'title': section_match.group(2).strip(),
                        'content': []
                    }
                    current_chapter['sections'].append(current_section)
                    structure['sections'].append(current_section)
                    continue
                
                # 提取关键要点
                key_words = ['概念', '技术', '发展', '趋势', '管理', '质量', '材料', '工艺']
                if any(keyword in text for keyword in key_words) and len(text) < 50:
                    structure['key_points'].append(text)
            
            elif item['type'] == 'paragraph' and current_section:
                if len(item['text']) > 20:
                    current_section['content'].append(item['text'])
        
        # 如果没有识别到章节，使用第一个标题作为文档标题
        if not structure['chapters'] and self.doc_content:
            for item in self.doc_content:
                if item['type'] == 'heading':
                    structure['title'] = item['text']
                    break
        
        return structure
    
    def create_ppt_from_structure(self, structure, output_path):
        """根据分析的结构创建PPT"""
        try:
            prs = Presentation()
            
            # 1. 封面页
            self._create_title_slide(prs, structure.get('title', '机械制造技术导论'))
            
            # 2. 目录页
            if structure['chapters']:
                self._create_toc_slide(prs, structure)
            
            # 3. 内容页
            if structure['chapters']:
                for chapter in structure['chapters']:
                    # 章节标题页
                    chapter_overview = self.summarize_chapter(chapter['title'], chapter['sections'])
                    self._create_chapter_title_slide(prs, chapter['title'], chapter_overview)
                    
                    # 小节内容页
                    for section in chapter['sections']:
                        key_points = self.summarize_section(section['title'], section['content'])
                        self._create_content_slide(prs, section, key_points)
            else:
                # 如果没有识别出章节，直接处理内容
                self._create_slides_from_content(prs, self.doc_content)
            
            # 4. 执行摘要页
            executive_summary = self.create_executive_summary(structure)
            self._create_executive_summary_slide(prs, executive_summary)
            
            # 5. 结束页
            self._create_end_slide(prs)
            
            prs.save(output_path)
            print(f"PPT生成成功: {output_path}")
            return True
            
        except Exception as e:
            print(f"创建PPT时出错: {str(e)}")
            return False

    def _create_slides_from_content(self, prs, content):
        """直接从内容创建幻灯片"""
        current_content = []
        slide_num = 0
        
        for item in content:
            if item['type'] == 'heading' and current_content:
                # 遇到新标题，创建幻灯片
                self._create_generic_slide(prs, current_content, f"内容页 {slide_num+1}")
                slide_num += 1
                current_content = []
            
            current_content.append(item)
            
            # 每5个内容项创建一个幻灯片
            if len(current_content) >= 5:
                self._create_generic_slide(prs, current_content, f"内容页 {slide_num+1}")
                slide_num += 1
                current_content = []
        
        # 处理剩余内容
        if current_content:
            self._create_generic_slide(prs, current_content, f"内容页 {slide_num+1}")

    def _create_generic_slide(self, prs, content_items, title):
        """创建通用内容幻灯片"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        title_shape.text = title
        
        content_shape = slide.placeholders[1]
        tf = content_shape.text_frame
        tf.clear()
        
        for i, item in enumerate(content_items):
            p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
            if item['type'] == 'heading':
                p.text = f"• {item['text']}"
                p.font.bold = True
            else:
                p.text = f"  {item['text'][:100]}..." if len(item['text']) > 100 else f"  {item['text']}"
            p.level = 0
            p.font.size = Pt(16)
            p.space_after = Pt(8)
    
    def _create_title_slide(self, prs, title):
        """创建标题页"""
        slide_layout = prs.slide_layouts[0]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        subtitle_shape = slide.placeholders[1]
        
        title_shape.text = title
        api_status = "（AI智能提炼）" if self.use_api else "（基础版）"
        subtitle_shape.text = f"文档内容自动生成{api_status}"
    
    def _create_toc_slide(self, prs, structure):
        """创建目录页"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        title_shape.text = "目录"
        
        content_shape = slide.placeholders[1]
        tf = content_shape.text_frame
        tf.clear()
        
        for i, chapter in enumerate(structure['chapters'], 1):
            p = tf.paragraphs[0] if i == 1 else tf.add_paragraph()
            p.text = f"{i}. {chapter['title']}"
            p.level = 0
            p.font.size = Pt(18)
            
            for j, section in enumerate(chapter['sections'][:2]):
                p = tf.add_paragraph()
                p.text = f"  {section['number']} {section['title']}"
                p.level = 1
                p.font.size = Pt(14)
    
    def _create_chapter_title_slide(self, prs, chapter_title, overview):
        """创建章节标题页"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        title_shape.text = chapter_title
        
        content_shape = slide.placeholders[1]
        content_shape.text = overview if overview else "本章主要内容概述"
    
    def _create_content_slide(self, prs, section, key_points):
        """创建内容幻灯片"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        title_shape.text = f"{section['number']} {section['title']}"
        
        content_shape = slide.placeholders[1]
        tf = content_shape.text_frame
        tf.clear()
        
        if not key_points:
            key_points = self._extract_key_points(section['content'], 6)
        
        for i, point in enumerate(key_points):
            p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
            p.text = f"• {point}"
            p.level = 0
            p.font.size = Pt(16)
            p.space_after = Pt(10)
    
    def _create_executive_summary_slide(self, prs, summary_points):
        """创建执行摘要页"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        title_shape.text = "核心要点总结"
        
        content_shape = slide.placeholders[1]
        tf = content_shape.text_frame
        tf.clear()
        
        for i, point in enumerate(summary_points):
            p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
            p.text = point if point.startswith('•') else f"• {point}"
            p.level = 0
            p.font.size = Pt(16)
            p.font.bold = True
            p.space_after = Pt(12)
    
    def _create_end_slide(self, prs):
        """创建结束页"""
        slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(slide_layout)
        
        title_shape = slide.shapes.title
        title_shape.text = "谢谢观看"
        
        content_shape = slide.placeholders[1]
        api_status = "（基于DeepSeek AI提炼）" if self.use_api else ""
        content_shape.text = f"Q & A{api_status}"
    
    def _extract_key_points(self, content_list, max_points):
        """从内容中提取关键要点（基础方法）"""
        key_points = []
        
        for content in content_list:
            sentences = re.split(r'[。！？]', content)
            for sentence in sentences:
                sentence = sentence.strip()
                if len(sentence) > 10 and len(sentence) < 100:
                    key_words = ['是', '包括', '分为', '具有', '通过', '实现', '提高', '降低']
                    if any(key_word in sentence for key_word in key_words):
                        if sentence not in key_points and len(key_points) < max_points:
                            key_points.append(sentence)
            
            if len(key_points) < max_points and len(content) < 150:
                if content not in key_points:
                    key_points.append(content)
            
            if len(key_points) >= max_points:
                break
        
        return key_points
    
    def convert(self, docx_path, output_ppt_path=None):
        """主转换函数"""
        if output_ppt_path is None:
            base_name = os.path.splitext(docx_path)[0]
            api_status = "_AI提炼" if self.use_api else "_基础版"
            output_ppt_path = f"{base_name}{api_status}.pptx"
        
        print(f"开始处理文档: {docx_path}")
        if self.use_api:
            print("🚀 启用DeepSeek API智能提炼功能")
        else:
            print("⚠ 使用基础内容提取模式")
        
        # 1. 读取Word文档
        if not self.read_docx(docx_path):
            return False
        
        # 2. 分析文档结构
        structure = self.analyze_content_structure()
        print(f"分析完成: 发现 {len(structure['chapters'])} 个章节，{len(structure['sections'])} 个小节")
        
        # 3. 生成PPT
        if self.create_ppt_from_structure(structure, output_ppt_path):
            print("🎉 转换完成!")
            return True
        else:
            print("❌ 转换失败!")
            return False


def main():
    """主函数"""
    print("=" * 60)
    print("          Word文档转PPT智能生成工具")
    print("=" * 60)
    
    # 配置DeepSeek API密钥 - 请取消注释并填入您的API密钥
    # DEEPSEEK_API_KEY = "sk-your-api"
    
    # 如果没有配置API密钥，使用None
    DEEPSEEK_API_KEY = None
    
    # 或者从环境变量获取
    # DEEPSEEK_API_KEY = os.getenv('DEEPSEEK_API_KEY')
    
    # 文档路径 - 修改为您的实际路径
    docx_path = input("请输入Word文档路径: ").strip()
    if not docx_path:
        docx_path = r"e:\temp\img2ppt\doc_folder\06-第1章.docx"  # 默认路径
    
    # 创建转换器
    converter = DocxToPptConverter(api_key=DEEPSEEK_API_KEY)
    
    # 执行转换
    if converter.convert(docx_path):
        output_file = f"{os.path.splitext(docx_path)[0]}_{'AI提炼' if converter.use_api else '基础版'}.pptx"
        print(f"\n✅ 转换成功！")
        print(f"📁 输出文件: {output_file}")
        print(f"🔧 模式: {'AI智能提炼' if converter.use_api else '基础提取'}")
        
        # 尝试打开生成的PPT
        try:
            if os.name == 'nt' and os.path.exists(output_file):
                os.startfile(output_file)
                print("📂 已自动打开生成的PPT文件")
        except Exception as e:
            print(f"⚠ 无法自动打开PPT文件: {str(e)}")
    else:
        print(f"\n❌ 转换失败")


if __name__ == "__main__":
    # 检查必要库是否已安装
    try:
        from docx import Document
        from pptx import Presentation
        import requests
    except ImportError as e:
        print(f"❌ 缺少必要的库: {e}")
        print("请运行以下命令安装:")
        print("pip install python-docx python-pptx requests")
        exit(1)
    
    main()